package common.serializer.impl;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import common.serializer.Serializer;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.lang.reflect.Type;

/**
 * @Desc: ""
 * @Author: caixiang
 * @DATE: 2020/9/22 13:25
 */
public class JacksonSerializer implements Serializer {
    private static final Logger logger = LoggerFactory.getLogger(JacksonSerializer.class);
    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.disable(SerializationFeature.INDENT_OUTPUT);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        mapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER,true);
        mapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);
        mapper.configure(JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS,true);
        mapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS,true);
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES,true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS,true);
    }
    private final JavaType type;
    public JacksonSerializer(JavaType javaType){
        this.type = javaType;
    }
    public JacksonSerializer(Type type){
        this.type = mapper.getTypeFactory().constructType(type);
    }
    public static JacksonSerializer createParametricType(Class<?> cls){
        return new JacksonSerializer(mapper.getTypeFactory().constructType(cls));
    }

    @Override
    public byte[] serializerToBytes(Object data) {
        try {
            return mapper.writeValueAsBytes(data);
        }catch (Exception exception){
            logger.error("序列化出错",exception);
        }
        return null;
    }

    //对象不仅仅是可以序列化成字节数组 也可以序列化成字符串
    @Override
    public String serializerToString(Object data) {
        try {
            return mapper.writeValueAsString(data);
        }catch (Exception exception){
            logger.error("序列化出错",exception);
        }
        return null;
    }

    @Override
    public <T> T deSerializer(String content) {
        try {
            return mapper.readValue(content,type);
        }catch (Exception exception){
            logger.error("序列化出错",exception);
        }
        return null;
    }

    @Override
    public <T> T deSerializer(byte[] content) {
        try {
            return mapper.readValue(content,type);
        }catch (Exception exception){
            logger.error("序列化出错",exception);
        }
        return null;
    }
}
